package com.tanhua.dubbo.api.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.tanhua.dubbo.api.SoulApi;
import com.tanhua.dubbo.mapper.SoulLockMapper;
import com.tanhua.dubbo.mapper.SoulRuleMapper;
import com.tanhua.dubbo.pojo.*;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@DubboService(version = "1.0.0")
public class SoulApiImpl implements SoulApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private SoulRuleMapper soulRuleMapper;

    @Autowired
    private SoulLockMapper soulLockMapper;

    @Override
    public Object getPapers(Long userId) {
        //获取所有问卷
        Query query = new Query();
        List<Paper> paperList = this.mongoTemplate.find(query, Paper.class);

        //查询用户是否解锁,设置上一次回答的问卷id
        for (Paper paper : paperList) {
            QueryWrapper<SoulLock> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId);
            queryWrapper.eq("paper_id", paper.getId());
            SoulLock soulLock = this.soulLockMapper.selectOne(queryWrapper);
            Integer isLock = soulLock.getIsLock();
            paper.setIsLock(isLock);

            Query paperRusultQuery = Query.query(Criteria.where("userId").is(Convert.toStr(userId))
                    .and("paperId").is(paper.getId()));
            PaperResult paperResult = this.mongoTemplate.findOne(paperRusultQuery, PaperResult.class);
            if (ObjectUtil.isNotEmpty(paperResult)) {
                paper.setReportId(paperResult.getId());
            }
        }
        return paperList;
    }

    @Override
    public Object submitPaper(Map<String, Object> param, String userId) {
        List<Map<String, String>> answers = (List<Map<String, String>>) param.get("answers");
        //声明问卷id
        String paperId = null;
        //获取所有的问卷
        Query query = new Query();
        List<Paper> paperList = this.mongoTemplate.find(query, Paper.class);
        //判断用户做的是哪一份问卷
        for (Paper paper : paperList) {
            List<PaperQuestion> questionList = paper.getQuestions();
            if (ObjectUtil.equal(questionList.get(0).getId(), answers.get(0).get("questionId"))) {
                paperId = paper.getId();
            }
        }
        //根据用户id和paperid获取问卷等级,解锁该用户等级+1的问卷,条件:问卷等级<3
        QueryWrapper<SoulLock> lockQueryWrapper = new QueryWrapper<>();
        lockQueryWrapper.eq("user_id", userId);
        lockQueryWrapper.eq("paper_id", paperId);
        SoulLock soulLock = this.soulLockMapper.selectOne(lockQueryWrapper);
        Integer level = soulLock.getLevel();
        if(level < 3) {
            lockQueryWrapper = new QueryWrapper<>();
            lockQueryWrapper.eq("user_id", userId);
            lockQueryWrapper.eq("level", level + 1);
            SoulLock soulLock2 = this.soulLockMapper.selectOne(lockQueryWrapper);
            soulLock2.setIsLock(0);
            UpdateWrapper<SoulLock> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("user_id", userId);
            updateWrapper.eq("paper_id", soulLock2.getPaperId());
            this.soulLockMapper.update(soulLock2, updateWrapper);
        }

        Integer result = 0;
        for (Map<String, String> answer : answers) {
//            String questionId = answer.get("questionId");
//            String optionId = answer.get("optionId");
//            String redisKey = "TESTSOUL_QUESTION_" + questionId;
//            String hashKey = optionId;
//            Boolean aBoolean = this.redisTemplate.opsForHash().hasKey(redisKey, hashKey);
//            Integer score = Convert.toInt(this.redisTemplate.opsForHash().get(redisKey, hashKey));
//            result += score;
            QueryWrapper<SoulRule> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("question_id", Convert.toInt(answer.get("questionId")));
            queryWrapper.eq("option_id", answer.get("optionId"));
            SoulRule soulRule = this.soulRuleMapper.selectOne(queryWrapper);
            Integer score = soulRule.getScore();
            result += score;
        }

        PaperResult paperResult = this.queryResult(userId, paperId);
        if(ObjectUtil.isNotEmpty(paperResult)) {
            //用户不是第一次问卷调查
            paperResult.setScore(result);
            if(result < 21) {
                paperResult.setConclusion("猫头鹰：他们的共同特质为重计划、条理、细节精准。在行为上，表现出喜欢理性思考与分析、较重视制度、结构、规范。他们注重执行游戏规则、循规蹈矩、巨细靡遗、重视品质、敬业负责。");
                paperResult.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/owl.png");

                List<PaperResultDimensions> dimensions = new ArrayList<>();
                dimensions.add(new PaperResultDimensions("内向", "70%"));
                dimensions.add(new PaperResultDimensions("理性", "75%"));
                dimensions.add(new PaperResultDimensions("判断", "80%"));
                dimensions.add(new PaperResultDimensions("可靠", "60%"));
                paperResult.setDimensions(dimensions);

            } else if(result >= 21 && result <= 40) {
                paperResult.setConclusion("白兔型：平易近人、敦厚可靠、避免冲突与不具批判性。在行为上，表现出不慌不忙、冷静自持的态度。他们注重稳定与中长程规划，现实生活中，常会反思自省并以和谐为中心，即使面对困境，亦能泰然自若，从容应付。");
                paperResult.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/rabbit.png");

                List<PaperResultDimensions> dimensions = new ArrayList<>();
                dimensions.add(new PaperResultDimensions("稳定", "70%"));
                dimensions.add(new PaperResultDimensions("友善", "75%"));
                dimensions.add(new PaperResultDimensions("耐心", "80%"));
                dimensions.add(new PaperResultDimensions("可靠", "80%"));
                paperResult.setDimensions(dimensions);

            } else if(result >= 41 && result <= 55) {
                paperResult.setConclusion("狐狸型 ：人际关系能力极强，擅长以口语表达感受而引起共鸣，很会激励并带动气氛。他们喜欢跟别人互动，重视群体的归属感，基本上是比较「人际导向」。由于他们富同理心并乐于分享，具有很好的亲和力，在服务业、销售业、传播业及公共关系等领域中，狐狸型的领导者都有很杰出的表现。");
                paperResult.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/fox.png");

                List<PaperResultDimensions> dimensions = new ArrayList<>();
                dimensions.add(new PaperResultDimensions("外向", "70%"));
                dimensions.add(new PaperResultDimensions("自信", "75%"));
                dimensions.add(new PaperResultDimensions("乐观", "80%"));
                dimensions.add(new PaperResultDimensions("热情", "60%"));
                paperResult.setDimensions(dimensions);
            } else if(result >= 56) {
                paperResult.setConclusion("狮子型：性格为充满自信、竞争心强、主动且企图心强烈，是个有决断力的领导者。一般而言，狮子型的人胸怀大志，勇于冒险，看问题能够直指核心，并对目标全力以赴。\n" +
                        "他们在领导风格及决策上，强调权威与果断，擅长危机处理，此种性格最适合开创性与改革性的工作。");
                paperResult.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/lion.png");

                List<PaperResultDimensions> dimensions = new ArrayList<>();
                dimensions.add(new PaperResultDimensions("外向", "80%"));
                dimensions.add(new PaperResultDimensions("自信", "85%"));
                dimensions.add(new PaperResultDimensions("果断", "80%"));
                dimensions.add(new PaperResultDimensions("强势", "90%"));
                paperResult.setDimensions(dimensions);
            }
            this.mongoTemplate.save(paperResult);
            return paperResult.getId();
        }

        //用户第一次问卷调查
        paperResult = new PaperResult();
        paperResult.setUserId(userId);
        paperResult.setScore(result);
        paperResult.setPaperId(paperId);
        if(result < 21) {
            paperResult.setId(ObjectId.get().toHexString());
            paperResult.setConclusion("猫头鹰：他们的共同特质为重计划、条理、细节精准。在行为上，表现出喜欢理性思考与分析、较重视制度、结构、规范。他们注重执行游戏规则、循规蹈矩、巨细靡遗、重视品质、敬业负责。");
            paperResult.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/owl.png");

            List<PaperResultDimensions> dimensions = new ArrayList<>();
            dimensions.add(new PaperResultDimensions("内向", "70%"));
            dimensions.add(new PaperResultDimensions("理性", "75%"));
            dimensions.add(new PaperResultDimensions("判断", "80%"));
            dimensions.add(new PaperResultDimensions("可靠", "60%"));
            paperResult.setDimensions(dimensions);

        } else if(result >= 21 && result <= 40) {
            paperResult.setId(ObjectId.get().toHexString());
            paperResult.setConclusion("白兔型：平易近人、敦厚可靠、避免冲突与不具批判性。在行为上，表现出不慌不忙、冷静自持的态度。他们注重稳定与中长程规划，现实生活中，常会反思自省并以和谐为中心，即使面对困境，亦能泰然自若，从容应付。");
            paperResult.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/rabbit.png");

            List<PaperResultDimensions> dimensions = new ArrayList<>();
            dimensions.add(new PaperResultDimensions("稳定", "70%"));
            dimensions.add(new PaperResultDimensions("友善", "75%"));
            dimensions.add(new PaperResultDimensions("耐心", "80%"));
            dimensions.add(new PaperResultDimensions("可靠", "80%"));
            paperResult.setDimensions(dimensions);

        } else if(result >= 41 && result <= 55) {
            paperResult.setId(ObjectId.get().toHexString());
            paperResult.setConclusion("狐狸型 ：人际关系能力极强，擅长以口语表达感受而引起共鸣，很会激励并带动气氛。他们喜欢跟别人互动，重视群体的归属感，基本上是比较「人际导向」。由于他们富同理心并乐于分享，具有很好的亲和力，在服务业、销售业、传播业及公共关系等领域中，狐狸型的领导者都有很杰出的表现。");
            paperResult.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/fox.png");

            List<PaperResultDimensions> dimensions = new ArrayList<>();
            dimensions.add(new PaperResultDimensions("外向", "70%"));
            dimensions.add(new PaperResultDimensions("自信", "75%"));
            dimensions.add(new PaperResultDimensions("乐观", "80%"));
            dimensions.add(new PaperResultDimensions("热情", "60%"));
            paperResult.setDimensions(dimensions);
        } else if(result >= 56) {
            paperResult.setId(ObjectId.get().toHexString());
            paperResult.setConclusion("狮子型：性格为充满自信、竞争心强、主动且企图心强烈，是个有决断力的领导者。一般而言，狮子型的人胸怀大志，勇于冒险，看问题能够直指核心，并对目标全力以赴。\n" +
                    "他们在领导风格及决策上，强调权威与果断，擅长危机处理，此种性格最适合开创性与改革性的工作。");
            paperResult.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/lion.png");

            List<PaperResultDimensions> dimensions = new ArrayList<>();
            dimensions.add(new PaperResultDimensions("外向", "80%"));
            dimensions.add(new PaperResultDimensions("自信", "85%"));
            dimensions.add(new PaperResultDimensions("果断", "80%"));
            dimensions.add(new PaperResultDimensions("强势", "90%"));
            paperResult.setDimensions(dimensions);
        }
        this.mongoTemplate.save(paperResult);
        return paperResult.getId();
    }

    /**
     * 根据用户id查询问卷结果
     * @param userId
     * @return
     */
    @Override
    public PaperResult queryResult(String userId, String paperId) {
        Query query = Query.query(Criteria.where("userId").is(userId)
                .and("paperId").is(paperId));
        PaperResult paperResult = this.mongoTemplate.findOne(query, PaperResult.class);
        return paperResult;
    }

    /**
     * 根据报告id查找结果
     * @param id
     * @return
     */
    @Override
    public PaperResult getResult(String id) {

        return this.mongoTemplate.findById(new ObjectId(id), PaperResult.class);

    }

    /**
     * 根据分数查相似用户
     * @param score
     * @return
     */
    @Override
    public List<Object> querySimilarUser(Integer score, Long userId) {
        Query query = Query.query(Criteria.where("score").lte(score + 5)
                .andOperator(Criteria.where("score").gte(score - 5).and("userId").nin(userId)));
        List<PaperResult> paperResultList = this.mongoTemplate.find(query, PaperResult.class);

        List<Object> userIdList = new ArrayList<>();
        for (PaperResult paperResult : paperResultList) {
            String uid = paperResult.getUserId();
            userIdList.add(uid);
        }
        return userIdList;
    }
}
